package com.zmc.order.config.mq;

import com.zmc.common.constant.QueueConstant;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;
/*
*
* 延时队列：订单超时自动关闭
*
*
* 消息有哪几种情况成为死信
* 1、消费者拒收消息 （basic.reject/ basic.nack） ，并且没有重新入队requeue=false
* 2、消息在队列中未被消费，且超过队列或者消息本身的过期时间TTL(time-to-live)
* 3、队列的消息长度达到极限
* 结果：消息成为死信后，如果该队列绑定了死信交换机，则消息会被死信交换机重新路由到死信队列
*
*
* */

/**
 * @author zmc
 * 延时关单
 */
@Configuration
public class OrderDelayCancelQueueConfig {

    @Value("${order.expire-time}")
    private Long expireTime;


    /**
     * 创建死信交换机
     */
    @Bean("orderDeadLetterExchange")
    public Exchange orderDeadLetterExchange() {
        return new TopicExchange(QueueConstant.ORDER_DEAD_LETTER_EXCHANGE, true, false);
    }

    /**
     * 创建死信队列
     */
    @Bean("orderDeadLetterQueue")
    public Queue orderDeadLetterQueue() {
        return QueueBuilder.durable(QueueConstant.ORDER_DEAD_LETTER_QUEUE).build();
    }

    /**
     * 绑定死信交换机和死信队列
     */
    @Bean("orderDeadLetterBinding")
    public Binding orderDeadLetterBinding(@Qualifier("orderDeadLetterQueue") Queue queue, @Qualifier("orderDeadLetterExchange")Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(QueueConstant.ORDER_DEAD_LETTER_QUEUE_ROUTING_KEY).noargs();
    }


    /**
     * 创建订单交换机
     */
    @Bean("orderExchange")
    public Exchange orderExchange() {
        return new TopicExchange(QueueConstant.ORDER_EXCHANGE, true, false);
    }

    /**
     * 创建订单队列
     */
    @Bean("orderQueue")
    public Queue orderQueue() {
        Map<String, Object> args = new HashMap<>(3);
        //消息过期后，进入到死信交换机
        args.put("x-dead-letter-exchange", QueueConstant.ORDER_DEAD_LETTER_EXCHANGE);
        //消息过期后，进入到死信交换机的路由key
        args.put("x-dead-letter-routing-key", QueueConstant.ORDER_DEAD_LETTER_QUEUE_ROUTING_KEY);
        //过期时间，单位毫秒
        args.put("x-message-ttl", expireTime * 60 * 1000);
        return QueueBuilder.durable(QueueConstant.ORDER_QUEUE).withArguments(args).build();
    }

    /**
     * 绑定订单交换机和队列
     */
    @Bean("orderBinding")
    public Binding orderBinding(@Qualifier("orderQueue") Queue queue, @Qualifier("orderExchange")Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(QueueConstant.ORDER_QUEUE_ROUTING_KEY).noargs();
    }


}
